Initial Analysis
How is life expectancy distributed when comparing developed countries to underdeveloped ones?
life_expectancy_1 <- life_expectancy %>%
select(Country, `Life expectancy`, Year) %>%
filter(Country %in% c("Russian Federation", "United Kingdom of Great Britain and Northern Ireland", "Japan", "United States of America", "Brazil", "Costa Rica", "Australia", "New Zealand", "Indonesia", "Swaziland", "Central African Republic", "Egpyt")) %>%
drop_na(Country, `Life expectancy`, Year) %>%
group_by(Country, Year)
life_expectancy_1[life_expectancy_1== "Russian Federation"] <- "Russia"
life_expectancy_1[life_expectancy_1== "United Kingdom of Great Britain and Northern Ireland"] <- "UK"
life_expectancy_1[life_expectancy_1== "Central African Republic"] <- "CAR"
life_expectancy_1[life_expectancy_1== "United States of America"] <- "USA"
life_expectancy_1 %>%
filter(Country %in% c("Russia", "UK", "Japan", "USA", "Mexico", "Brazil", "Argentina", "Peru", "Australia", "New Zealand", "Indonesia", "Swaziland", "CAR", "Egypt")) %>%
ggplot(aes(color = Country, x = `Life expectancy`)) +
labs(title = "Life Expectancies by Country",
x = "",
subtitle = "Life Expectancy Distributions Across Selected Countries \n As we can see, Japan has the highest median age, while Central African Republic has the lowest.",
caption = "By Callum Moir & Gugo Babayan") +
theme_classic() +
theme(plot.title.position = "plot",
plot.title = element_text(size = 20, face = "bold"),
plot.subtitle = element_text(size = 10, face = "italic")) +
geom_boxplot() +
geom_vline(aes(xintercept = median(`Life expectancy`, na.rm = TRUE)), color = "blue")

In this initial graph, we have hand-selected 10 countries from across the world according to personal associations and/or whether or not they are classified as ‘developed’ or ‘developing’ according to the data set. The blue line illustrates the median life expectancy of these countries combined, and shows that 5 of the selected countries fall on either side of this divide. Japan tops the life expectancy, while the Central African Republic (CAR) is at the bottom.
This next plot nicely supports our point that developed countries have much higher average life expectancies than developing ones:
life_expectancy %>%
drop_na(`Life expectancy`) %>%
ggplot(aes(x=Year,y= `Life expectancy`, color=Status))+
geom_jitter()+
geom_smooth(method = "lm", color = "black")+
transition_states(Status,
transition_length = 2,
state_length = 1) +
exit_shrink() +
enter_recolor(color = "lightblue") +
exit_recolor(color = "lightblue")+
labs(title = "Average Life Expectancy According to Country Status",
subtitle = "Status: {closest_state}",
x = "",
y = "Life Expectancy")+
theme(legend.position = "none")
anim_save("status_anim.gif")
knitr::include_graphics("status_anim.gif")

This graph shows the differences in life expectancy according to your country’s development status. The red data points represent developed countries, while the blue represents developing countries. The animation makes it clear, through the black regression line, that the average life expectancy for developed countries is much higher than for developing ones.
life_expectancy %>%
group_by(Year, Status) %>%
summarize(LE_time = sum(`Life expectancy`)) %>%
ungroup() %>%
complete(Status, Year,
fill = list(LE_time = 0)) %>%
mutate(variety = fct_reorder(Status,
LE_time,
sum,
.desc = FALSE)) %>%
group_by(Status) %>%
mutate(cum_LE_time = cumsum(LE_time)) %>%
ggplot(aes(x = Year,
y = cum_LE_time,
fill = Status)) +
geom_area(position = "stack") +
geom_text(aes(label = Status),
position = "stack",
check_overlap = TRUE) +
scale_fill_viridis_d(option = "magma") +
theme(legend.position = "none") +
transition_reveal(Year) +
labs(title = "Cumulative Life Expectancy",
subtitle = "Year: {frame_along}",
x = "",
y = "")
anim_save("Rate.gif")
knitr::include_graphics("Rate.gif")

This animation takes the cumulative life expectancies from developed and developing countries from 2000-2015. It nicely illustrates that since 2000, the gap between life expectancies in developed countries has increased at a faster rate relative to that of developing countries.
Comparing the Selected Countries With by Examining Changes over Time
These next graphs illustrate how our selected countries differ in life expectancies and rates of improvement over the years.
life_expectancy_1 <- life_expectancy %>%
select(Country, `Life expectancy`, Year) %>%
filter(Country %in% c("Russian Federation", "United Kingdom of Great Britain and Northern Ireland", "Japan", "United States of America", "Brazil", "Costa Rica", "Australia", "New Zealand", "Indonesia", "Swaziland", "Central African Republic", "Egpyt")) %>%
drop_na(Country, `Life expectancy`, Year) %>%
group_by(Country, Year)
life_expectancy_1[life_expectancy_1== "Russian Federation"] <- "Russia"
life_expectancy_1[life_expectancy_1== "United Kingdom of Great Britain and Northern Ireland"] <- "UK"
life_expectancy_1[life_expectancy_1== "Central African Republic"] <- "CAR"
life_expectancy_1[life_expectancy_1== "United States of America"] <- "USA"
life_graph<- life_expectancy_1 %>%
ggplot(aes(x = Year, y = `Life expectancy`, color = Country)) +
geom_line() +
labs(title = "Life Expectancies by Country from 2000 to 2015", subtitle = "Date: 2000 to 2015", x = element_blank(), y = element_blank())+
theme(legend.position = "none")+
facet_wrap("Country", scales = "free_y")+
theme(
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank())
ggplotly(life_graph)
The above interactive graph allows you to hover over the years to see what each country’s life expectancy was during that time period. They also show how each country’s life expectancy has grown over time. We see that the USA’s has grown quite constantly, while the UK’s has dipped in more recent years.
life_expectancy_1 <- life_expectancy %>%
select(Country, `Life expectancy`, Year) %>%
filter(Country %in% c("Russian Federation", "United Kingdom of Great Britain and Northern Ireland", "Japan", "United States of America", "Brazil", "Costa Rica", "Australia", "New Zealand", "Indonesia", "Swaziland", "Central African Republic", "Egpyt")) %>%
drop_na(Country, `Life expectancy`, Year) %>%
group_by(Country, Year)
life_expectancy_1[life_expectancy_1== "Russian Federation"] <- "Russia"
life_expectancy_1[life_expectancy_1== "United Kingdom of Great Britain and Northern Ireland"] <- "UK"
life_expectancy_1[life_expectancy_1== "Central African Republic"] <- "CAR"
life_expectancy_1[life_expectancy_1== "United States of America"] <- "USA"
life_expectancy_1 %>%
ggplot(aes(x = Year, y = `Life expectancy`, color = Country)) +
geom_line() +
labs(title = "Life Expectancies by Country from 2000 to 2015", subtitle = "Date: 2000 to 2015", x = element_blank(), y = element_blank()) +
transition_reveal(Year)
anim_save("Test.gif")
knitr::include_graphics("Test.gif")

This graph shows the same trends as the one above, but makes it easier for the viewer to compare these countries’ rates of life expectancy growth over time, and to see how low some are relative to others.
Using Regressions to Determine Trends of other Variables
plot1 <- life_expectancy %>%
filter(Country %in% c("Russian Federation", "United Kingdom of Great Britain and Northern Ireland", "Japan", "United States of America", "Brazil", "Australia", "New Zealand")) %>%
group_by(Country) %>%
drop_na(Alcohol) %>%
ggplot(aes(x = Alcohol, y = `Life expectancy`)) +
geom_jitter() +
geom_smooth(method = "lm") +
labs(x = "Alcohol Consumption (Percentage of Population)", y = "Life Expectancy")
plot2 <- life_expectancy %>%
filter(Country %in% c("Russian Federation", "United Kingdom of Great Britain and Northern Ireland", "Japan", "United States of America", "Brazil", "Australia", "New Zealand")) %>%
group_by(Country) %>%
drop_na(`Total expenditure`) %>%
ggplot(aes(x = `Total expenditure`, y = `Life expectancy`)) +
geom_jitter() +
geom_smooth(method = "lm") +
labs(x = "Percentage of Government Spending on Healthcare", y = "Life Expectancy")
plot_grid(plot1, plot2, labels = "AUTO")

To expand on our findings, we decided to conduct our own research into regressions and correlations in order to determine relationships between certain variables and life expectancies. In the above graph, we can see that on average, across our selected countries, there is a strong negative correlation between alcohol consumption and life expectancy. That is, as alcohol consumption increases, life expectancy tends to fall. The graph next to it shows a strong positive correlation between the percentage of government spending on healthcare and life expectancy. That is, as the governments across these countries spends a higher percentage of their budget on improving healthcare, life expectancy tends tio increase.
correlation1<- life_expectancy %>%
filter(Status=="Developed") %>%
select(-Year, -Country, -Status) %>%
drop_na()
correlation_anim<-
corrplot(cor(correlation1),type="upper",method="circle",title="Correlation plot between variables",mar=c(0.1,0.1,0.1,0.1), insig="blank", na.label = " ")

correlation2<- life_expectancy %>%
filter(Status=="Developing") %>%
select(-Year, -Country, -Status) %>%
drop_na()
correlation_anim<-
corrplot(cor(correlation2),type="upper",method="circle",title="Correlation plot between variables",mar=c(0.1,0.1,0.1,0.1), insig="blank")

Conclusion and Limitations
The main findings we took from our project are (i) there is a clear distinction between life expectancies in developed vs. developing countries. Developed countries tend to have higher life expectancies, while developing countries tend to have much lower life expectancies. Furthermore, we can see that the life expectancies over time in developed countries is increasing at a much faster rate than that in developing countries. (ii) Increased alcohol consumption tends to decrease life expectancy, while increased government spending on healthcare tends to increase life expectancy.
LS0tCnRpdGxlOiAiSG93IGhhcyBsaWZlIGV4cGVjdGFuY3kgY2hhbmdlZCBvdmVyIHRoZSB5ZWFycyBhbmQgd2hhdCBmYWN0b3JzIGhhdmUgY29udHJpYnV0ZWQgdG8gdGhlc2UgY2hhbmdlcz8iCnN1YnRpdGxlOiAiRGV2ZWxvcGVkIHZzLiBVbmRldmVsb3BlZCBDb3VudHJpZXMiCmF1dGhvcnM6ICJDYWxsdW0gTW9pciAmIEd1Z28gQmFiYXlhbiIKZGF0ZTogIjI5IEFwcmlsIDIwMjIiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIGtlZXBfbWQ6IFRSVUUKICAgIHRvYzogVFJVRQogICAgdG9jX2Zsb2F0OiBUUlVFCiAgICBkZl9wcmludDogcGFnZWQKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogaGlkZSAKICAgIHRoZW1lOiBjb3NtbwotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGVycm9yPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UpCmBgYAoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKSAgICAgIyBmb3IgZGF0YSBjbGVhbmluZyBhbmQgcGxvdHRpbmcKbGlicmFyeShsdWJyaWRhdGUpICAgICAjIGZvciBkYXRlIG1hbmlwdWxhdGlvbgpsaWJyYXJ5KG9wZW5pbnRybykgICAgICMgZm9yIHRoZSBhYmJyMnN0YXRlKCkgZnVuY3Rpb24KbGlicmFyeShnZ21hcCkgICAgICAgICAjIGZvciBtYXBwaW5nIHBvaW50cyBvbiBtYXBzCmxpYnJhcnkoZ3Bsb3RzKSAgICAgICAgIyBmb3IgY29sMmhleCgpIGZ1bmN0aW9uCmxpYnJhcnkoUkNvbG9yQnJld2VyKSAgIyBmb3IgY29sb3IgcGFsZXR0ZXMKbGlicmFyeShzZikgICAgICAgICAgICAjIGZvciB3b3JraW5nIHdpdGggc3BhdGlhbCBkYXRhCmxpYnJhcnkobGVhZmxldCkgICAgICAgIyBmb3IgaGlnaGx5IGN1c3RvbWl6YWJsZSBtYXBwaW5nCmxpYnJhcnkoZ2d0aGVtZXMpICAgICAgIyBmb3IgbW9yZSB0aGVtZXMgKGluY2x1ZGluZyB0aGVtZV9tYXAoKSkKbGlicmFyeShwbG90bHkpICAgICAgICAjIGZvciB0aGUgZ2dwbG90bHkoKSAtIGJhc2ljIGludGVyYWN0aXZpdHkKbGlicmFyeShnZ2FuaW1hdGUpICAgICAjIGZvciBhZGRpbmcgYW5pbWF0aW9uIGxheWVycyB0byBnZ3Bsb3RzCmxpYnJhcnkoZ2lmc2tpKSAgICAgICAgIyBmb3IgY3JlYXRpbmcgdGhlIGdpZiAoZG9uJ3QgbmVlZCB0byBsb2FkIHRoaXMgbGlicmFyeSBldmVyeSB0aW1lLGJ1dCBuZWVkIGl0IGluc3RhbGxlZCkKbGlicmFyeSh0cmFuc2Zvcm1yKSAgICAjIGZvciAidHdlZW5pbmciIChnZ2FuaW1hdGUpCmxpYnJhcnkoc2hpbnkpICAgICAgICAgIyBmb3IgY3JlYXRpbmcgaW50ZXJhY3RpdmUgYXBwcwpsaWJyYXJ5KHBhdGNod29yaykgICAgICMgZm9yIG5pY2VseSBjb21iaW5pbmcgZ2dwbG90MiBncmFwaHMgIApsaWJyYXJ5KGd0KSAgICAgICAgICAgICMgZm9yIGNyZWF0aW5nIG5pY2UgdGFibGVzCmxpYnJhcnkocnZlc3QpICAgICAgICAgIyBmb3Igc2NyYXBpbmcgZGF0YQpsaWJyYXJ5KHJvYm90c3R4dCkgICAgICMgZm9yIGNoZWNraW5nIGlmIHlvdSBjYW4gc2NyYXBlIGRhdGEKbGlicmFyeShkcGx5cikKbGlicmFyeShtb2Rlcm5kaXZlKSAgICAgCmxpYnJhcnkoYnJvb20pICAgICAgICAgIApsaWJyYXJ5KGVxdWF0aW9tYXRpYykgICAKbGlicmFyeShjb3dwbG90KQpsaWJyYXJ5KGNvcnJwbG90KQp0aGVtZV9zZXQodGhlbWVfbWluaW1hbCgpKQpgYGAKCgpgYGB7cn0KI0ZvciBsb2FkaW5nIG91ciBkYXRhIHNldApsaWZlX2V4cGVjdGFuY3kgPC0gcmVhZF9jc3YoIkxpZmUgRXhwZWN0YW5jeSBEYXRhLmNzdiIpCmBgYAoKCiMgQmFja2dyb3VuZCBhbmQgSW50cm9kdWN0aW9uCgoKQXMgdHdvIGZyaWVuZHMgd2hvIGhhdmUgcmVjZW50bHkgc3RhcnRlZCBnb2luZyB0byB0aGUgZ3ltLCBvbmUgb2YgdGhlIGtleSBiZW5lZml0cyB3ZSBhbHdheXMgcmVhZCBvbmxpbmUgaXMgdGhhdCBsaWZ0aW5nIHdlaWdodHMgYWRkcyB5ZWFycyB0byB5b3VyIGxpZmUuIEFzIHN1Y2gsIHdoZW4gc2VhcmNoaW5nIGZvciBhIGRhdGEgc2V0IGZvciB0aGlzIHByb2plY3QsIHRoZSB3b3JkICJMaWZlIEV4cGVjdGFuY3kiIHBpcXVlZCBvdXIgaW50ZXJlc3QuIEFmdGVyIGV4YW1pbmluZyBzb21lIG9mIHRoZSBkZXRlcm1pbmFudHMgd2hpY2ggd2VudCBpbnRvIGl0LCB3ZSBkZWNpZGVkIHRoYXQgdGhpcyB3YXMgdGhlIGlkZWFsIGRhdGEgc2V0IGZvciB1cyEKCiMgRGF0YSBDb2xsZWN0aW9uIGFuZCBDbGVhbmluZwoKCldlIGZvdW5kIHRoaXMgZGF0YSBzZXQgb24gS2FnZ2xlIC0gYSB2ZXJ5IHVzZWZ1bCB3ZWJzaXRlIGZ1bGwgb2YgaW50ZXJlc3RpbmcgZGF0YSBzZXRzLiBIZXJlIGlzIHRoZSBsaW5rOiBodHRwczovL3d3dy5rYWdnbGUuY29tL2NvZGUvc2hyZXN0aGFrdW5kdS9saWZlLWV4cGVjdGFuY3ktd2hvCgoKVXNpbmcgZGF0YSBmcm9tIHRoaXMgZGF0YSBzZXQsIHdlIHdpbGwgcHJlc2VudCBtdWx0aXBsZSB2aXN1YWxpemF0aW9ucyB3aGljaCBhaW0gdG8gYXNzZXNzIGxpZmUgZXhwZWN0YW5jeSBkaWZmZXJlbmNlcyBhbmQgY2hhbmdlcyBhY3Jvc3MgY291bnRyaWVzIGFuZCB5ZWFycy4gTW9yZW92ZXIsIHdlIGhvcGUgdG8gYXNzZXNzIHRoZSBpbXBhY3RzIG9mIGNlcnRhaW4gaW5kZXBlbmRlbnQgdmFyaWFibGVzIHN1Y2ggYXMgYWxjb2hvbCBjb25zdW1wdGlvbiBhbmQgaGVhbHRoY2FyZSBzcGVuZGluZyBvbiBsaWZlIGV4cGVjdGFuY3kuIFRoaXMgd2lsbCBiZSBkb25lIGJ5IHZpc3VhbGl6aW5nIHJlZ3Jlc3Npb25zLiAoUGxlYXNlIG5vdGU6IFRoaXMgaXMgYmV5b25kIHRoZSB0ZWFjaGluZ3Mgb2YgdGhpcyBjb3Vyc2UsIGJ1dCB3ZSB3YW50ZWQgdG8gc2VlayByZWxhdGlvbnNoaXBzIG91dCBvZiBpbnRlcmVzdCwgdXNpbmcgbWV0aG9kcyBmcm9tIG90aGVyIFN0YXRpc3RpY3MgY291cnNlcy4pCgoKIyBJbml0aWFsIEFuYWx5c2lzCgoKIyMgSG93IGlzIGxpZmUgZXhwZWN0YW5jeSBkaXN0cmlidXRlZCB3aGVuIGNvbXBhcmluZyBkZXZlbG9wZWQgY291bnRyaWVzIHRvIHVuZGVyZGV2ZWxvcGVkIG9uZXM/CgoKYGBge3IsIGZpZy53aWR0aD0xMCwgZmlnLmFsdD0gIkJveHBsb3RzIFNob3dpbmcgdGhlIGRpc3RyaWJ1dGlvbnMgYW5kIG1lZGlhbnMgYWNyb3NzIHZhcmlvdXMgaGFuZC1zZWxlY3RlZCBjb3VudHJpZXMuIn0KCmxpZmVfZXhwZWN0YW5jeV8xIDwtIGxpZmVfZXhwZWN0YW5jeSAlPiUgCiAgc2VsZWN0KENvdW50cnksIGBMaWZlIGV4cGVjdGFuY3lgLCBZZWFyKSAlPiUgCiAgZmlsdGVyKENvdW50cnkgJWluJSBjKCJSdXNzaWFuIEZlZGVyYXRpb24iLCAiVW5pdGVkIEtpbmdkb20gb2YgR3JlYXQgQnJpdGFpbiBhbmQgTm9ydGhlcm4gSXJlbGFuZCIsICJKYXBhbiIsICJVbml0ZWQgU3RhdGVzIG9mIEFtZXJpY2EiLCAgIkJyYXppbCIsICJDb3N0YSBSaWNhIiwgIkF1c3RyYWxpYSIsICJOZXcgWmVhbGFuZCIsICJJbmRvbmVzaWEiLCAiU3dhemlsYW5kIiwgIkNlbnRyYWwgQWZyaWNhbiBSZXB1YmxpYyIsICJFZ3B5dCIpKSAlPiUgCiAgZHJvcF9uYShDb3VudHJ5LCBgTGlmZSBleHBlY3RhbmN5YCwgWWVhcikgJT4lIAogIGdyb3VwX2J5KENvdW50cnksIFllYXIpCiAgbGlmZV9leHBlY3RhbmN5XzFbbGlmZV9leHBlY3RhbmN5XzE9PSAiUnVzc2lhbiBGZWRlcmF0aW9uIl0gPC0gIlJ1c3NpYSIKICBsaWZlX2V4cGVjdGFuY3lfMVtsaWZlX2V4cGVjdGFuY3lfMT09ICJVbml0ZWQgS2luZ2RvbSBvZiBHcmVhdCBCcml0YWluIGFuZCBOb3J0aGVybiBJcmVsYW5kIl0gPC0gIlVLIgogIGxpZmVfZXhwZWN0YW5jeV8xW2xpZmVfZXhwZWN0YW5jeV8xPT0gIkNlbnRyYWwgQWZyaWNhbiBSZXB1YmxpYyJdIDwtICJDQVIiCiAgbGlmZV9leHBlY3RhbmN5XzFbbGlmZV9leHBlY3RhbmN5XzE9PSAiVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhIl0gPC0gIlVTQSIKICAKbGlmZV9leHBlY3RhbmN5XzEgJT4lCiAgZmlsdGVyKENvdW50cnkgJWluJSBjKCJSdXNzaWEiLCAiVUsiLCAiSmFwYW4iLCAiVVNBIiwgIk1leGljbyIsICJCcmF6aWwiLCAiQXJnZW50aW5hIiwgIlBlcnUiLCAiQXVzdHJhbGlhIiwgIk5ldyBaZWFsYW5kIiwgIkluZG9uZXNpYSIsICJTd2F6aWxhbmQiLCAiQ0FSIiwgIkVneXB0IikpICU+JSAKICBnZ3Bsb3QoYWVzKGNvbG9yID0gQ291bnRyeSwgeCA9IGBMaWZlIGV4cGVjdGFuY3lgKSkgKwogIGxhYnModGl0bGUgPSAiTGlmZSBFeHBlY3RhbmNpZXMgYnkgQ291bnRyeSIsCiAgICAgICB4ID0gIiIsCiAgICAgICBzdWJ0aXRsZSA9ICJMaWZlIEV4cGVjdGFuY3kgRGlzdHJpYnV0aW9ucyBBY3Jvc3MgU2VsZWN0ZWQgQ291bnRyaWVzIFxuIEFzIHdlIGNhbiBzZWUsIEphcGFuIGhhcyB0aGUgaGlnaGVzdCBtZWRpYW4gYWdlLCB3aGlsZSBDZW50cmFsIEFmcmljYW4gUmVwdWJsaWMgaGFzIHRoZSBsb3dlc3QuIiwKICAgICAgIGNhcHRpb24gPSAiQnkgQ2FsbHVtIE1vaXIgJiBHdWdvIEJhYmF5YW4iKSArCiAgdGhlbWVfY2xhc3NpYygpICsgCiAgdGhlbWUocGxvdC50aXRsZS5wb3NpdGlvbiA9ICJwbG90IiwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGZhY2UgPSAiaXRhbGljIikpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdCA9IG1lZGlhbihgTGlmZSBleHBlY3RhbmN5YCwgbmEucm0gPSBUUlVFKSksIGNvbG9yID0gImJsdWUiKQpgYGAKCgpJbiB0aGlzIGluaXRpYWwgZ3JhcGgsIHdlIGhhdmUgaGFuZC1zZWxlY3RlZCAxMCBjb3VudHJpZXMgZnJvbSBhY3Jvc3MgdGhlIHdvcmxkIGFjY29yZGluZyB0byBwZXJzb25hbCBhc3NvY2lhdGlvbnMgYW5kL29yIHdoZXRoZXIgb3Igbm90IHRoZXkgYXJlIGNsYXNzaWZpZWQgYXMgJ2RldmVsb3BlZCcgb3IgJ2RldmVsb3BpbmcnIGFjY29yZGluZyB0byB0aGUgZGF0YSBzZXQuIFRoZSBibHVlIGxpbmUgaWxsdXN0cmF0ZXMgdGhlIG1lZGlhbiBsaWZlIGV4cGVjdGFuY3kgb2YgdGhlc2UgY291bnRyaWVzIGNvbWJpbmVkLCBhbmQgc2hvd3MgdGhhdCA1IG9mIHRoZSBzZWxlY3RlZCBjb3VudHJpZXMgZmFsbCBvbiBlaXRoZXIgc2lkZSBvZiB0aGlzIGRpdmlkZS4gSmFwYW4gdG9wcyB0aGUgbGlmZSBleHBlY3RhbmN5LCB3aGlsZSB0aGUgQ2VudHJhbCBBZnJpY2FuIFJlcHVibGljIChDQVIpIGlzIGF0IHRoZSBib3R0b20uCgoKVGhpcyBuZXh0IHBsb3QgbmljZWx5IHN1cHBvcnRzIG91ciBwb2ludCB0aGF0IGRldmVsb3BlZCBjb3VudHJpZXMgaGF2ZSBtdWNoIGhpZ2hlciBhdmVyYWdlIGxpZmUgZXhwZWN0YW5jaWVzIHRoYW4gZGV2ZWxvcGluZyBvbmVzOgoKCmBgYHtyLCBldmFsPUZBTFNFLGZpZy5oZWlnaHQ9IDQsIGZpZy53aWR0aD04fQpsaWZlX2V4cGVjdGFuY3kgJT4lIAogIGRyb3BfbmEoYExpZmUgZXhwZWN0YW5jeWApICU+JSAKICBnZ3Bsb3QoYWVzKHg9WWVhcix5PSBgTGlmZSBleHBlY3RhbmN5YCwgY29sb3I9U3RhdHVzKSkrCiAgZ2VvbV9qaXR0ZXIoKSsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvciA9ICJibGFjayIpKwogIHRyYW5zaXRpb25fc3RhdGVzKFN0YXR1cywgCiAgICAgICAgICAgICAgICAgICAgdHJhbnNpdGlvbl9sZW5ndGggPSAyLCAKICAgICAgICAgICAgICAgICAgICBzdGF0ZV9sZW5ndGggPSAxKSArCiAgZXhpdF9zaHJpbmsoKSArCiAgZW50ZXJfcmVjb2xvcihjb2xvciA9ICJsaWdodGJsdWUiKSArCiAgZXhpdF9yZWNvbG9yKGNvbG9yID0gImxpZ2h0Ymx1ZSIpKwogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBMaWZlIEV4cGVjdGFuY3kgQWNjb3JkaW5nIHRvIENvdW50cnkgU3RhdHVzIiwKICAgICAgIHN1YnRpdGxlID0gIlN0YXR1czoge2Nsb3Nlc3Rfc3RhdGV9IiwKICAgICAgIHggPSAiIiwKICAgICAgIHkgPSAiTGlmZSBFeHBlY3RhbmN5IikrCnRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYW5pbV9zYXZlKCJzdGF0dXNfYW5pbS5naWYiKQpgYGAKCgpgYGB7cn0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoInN0YXR1c19hbmltLmdpZiIpCmBgYAoKClRoaXMgZ3JhcGggc2hvd3MgdGhlIGRpZmZlcmVuY2VzIGluIGxpZmUgZXhwZWN0YW5jeSBhY2NvcmRpbmcgdG8geW91ciBjb3VudHJ5J3MgZGV2ZWxvcG1lbnQgc3RhdHVzLiBUaGUgcmVkIGRhdGEgcG9pbnRzIHJlcHJlc2VudCBkZXZlbG9wZWQgY291bnRyaWVzLCB3aGlsZSB0aGUgYmx1ZSByZXByZXNlbnRzIGRldmVsb3BpbmcgY291bnRyaWVzLiBUaGUgYW5pbWF0aW9uIG1ha2VzIGl0IGNsZWFyLCB0aHJvdWdoIHRoZSBibGFjayByZWdyZXNzaW9uIGxpbmUsIHRoYXQgdGhlIGF2ZXJhZ2UgbGlmZSBleHBlY3RhbmN5IGZvciBkZXZlbG9wZWQgY291bnRyaWVzIGlzIG11Y2ggaGlnaGVyIHRoYW4gZm9yIGRldmVsb3Bpbmcgb25lcy4KCgpgYGB7ciwgZXZhbD0gRkFMU0V9CmxpZmVfZXhwZWN0YW5jeSAlPiUgCiAgZ3JvdXBfYnkoWWVhciwgU3RhdHVzKSAlPiUgCiAgc3VtbWFyaXplKExFX3RpbWUgPSBzdW0oYExpZmUgZXhwZWN0YW5jeWApKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBjb21wbGV0ZShTdGF0dXMsIFllYXIsIAogICAgICAgICAgIGZpbGwgPSBsaXN0KExFX3RpbWUgPSAwKSkgJT4lIAogIG11dGF0ZSh2YXJpZXR5ID0gZmN0X3Jlb3JkZXIoU3RhdHVzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExFX3RpbWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5kZXNjID0gRkFMU0UpKSAlPiUgCiAgZ3JvdXBfYnkoU3RhdHVzKSAlPiUgCiAgbXV0YXRlKGN1bV9MRV90aW1lID0gY3Vtc3VtKExFX3RpbWUpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gWWVhciwgCiAgICAgICAgICAgICB5ID0gY3VtX0xFX3RpbWUsIAogICAgICAgICAgICAgZmlsbCA9IFN0YXR1cykpICsKICBnZW9tX2FyZWEocG9zaXRpb24gPSAic3RhY2siKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IFN0YXR1cyksCiAgICAgICAgICAgIHBvc2l0aW9uID0gInN0YWNrIiwgCiAgICAgICAgICAgIGNoZWNrX292ZXJsYXAgPSBUUlVFKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Qob3B0aW9uID0gIm1hZ21hIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIHRyYW5zaXRpb25fcmV2ZWFsKFllYXIpICArCiAgbGFicyh0aXRsZSA9ICJDdW11bGF0aXZlIExpZmUgRXhwZWN0YW5jeSIsCiAgICAgICBzdWJ0aXRsZSA9ICJZZWFyOiB7ZnJhbWVfYWxvbmd9IiwKICAgICAgIHggPSAiIiwKICAgICAgIHkgPSAiIikKYW5pbV9zYXZlKCJSYXRlLmdpZiIpCmBgYApgYGB7cn0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIlJhdGUuZ2lmIikKYGBgCgoKVGhpcyBhbmltYXRpb24gdGFrZXMgdGhlIGN1bXVsYXRpdmUgbGlmZSBleHBlY3RhbmNpZXMgZnJvbSBkZXZlbG9wZWQgYW5kIGRldmVsb3BpbmcgY291bnRyaWVzIGZyb20gMjAwMC0yMDE1LiBJdCBuaWNlbHkgaWxsdXN0cmF0ZXMgdGhhdCBzaW5jZSAyMDAwLCB0aGUgZ2FwIGJldHdlZW4gbGlmZSBleHBlY3RhbmNpZXMgaW4gZGV2ZWxvcGVkIGNvdW50cmllcyBoYXMgaW5jcmVhc2VkIGF0IGEgZmFzdGVyIHJhdGUgcmVsYXRpdmUgdG8gdGhhdCBvZiBkZXZlbG9waW5nIGNvdW50cmllcy4KCgojIyBDb21wYXJpbmcgdGhlIFNlbGVjdGVkIENvdW50cmllcyBXaXRoIGJ5IEV4YW1pbmluZyBDaGFuZ2VzIG92ZXIgVGltZQoKClRoZXNlIG5leHQgZ3JhcGhzIGlsbHVzdHJhdGUgaG93IG91ciBzZWxlY3RlZCBjb3VudHJpZXMgZGlmZmVyIGluIGxpZmUgZXhwZWN0YW5jaWVzIGFuZCByYXRlcyBvZiBpbXByb3ZlbWVudCBvdmVyIHRoZSB5ZWFycy4KCgpgYGB7ciwgZmlnLndpZHRoPTE4LCBmaWcuaGVpZ2h0PTEyfQpsaWZlX2V4cGVjdGFuY3lfMSA8LSBsaWZlX2V4cGVjdGFuY3kgJT4lIAogIHNlbGVjdChDb3VudHJ5LCBgTGlmZSBleHBlY3RhbmN5YCwgWWVhcikgJT4lIAogIGZpbHRlcihDb3VudHJ5ICVpbiUgYygiUnVzc2lhbiBGZWRlcmF0aW9uIiwgIlVuaXRlZCBLaW5nZG9tIG9mIEdyZWF0IEJyaXRhaW4gYW5kIE5vcnRoZXJuIElyZWxhbmQiLCAiSmFwYW4iLCAiVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhIiwgICJCcmF6aWwiLCAiQ29zdGEgUmljYSIsICJBdXN0cmFsaWEiLCAiTmV3IFplYWxhbmQiLCAiSW5kb25lc2lhIiwgIlN3YXppbGFuZCIsICJDZW50cmFsIEFmcmljYW4gUmVwdWJsaWMiLCAiRWdweXQiKSkgJT4lIAogIGRyb3BfbmEoQ291bnRyeSwgYExpZmUgZXhwZWN0YW5jeWAsIFllYXIpICU+JSAKICBncm91cF9ieShDb3VudHJ5LCBZZWFyKQoKICBsaWZlX2V4cGVjdGFuY3lfMVtsaWZlX2V4cGVjdGFuY3lfMT09ICJSdXNzaWFuIEZlZGVyYXRpb24iXSA8LSAiUnVzc2lhIgogIGxpZmVfZXhwZWN0YW5jeV8xW2xpZmVfZXhwZWN0YW5jeV8xPT0gIlVuaXRlZCBLaW5nZG9tIG9mIEdyZWF0IEJyaXRhaW4gYW5kIE5vcnRoZXJuIElyZWxhbmQiXSA8LSAiVUsiCiAgbGlmZV9leHBlY3RhbmN5XzFbbGlmZV9leHBlY3RhbmN5XzE9PSAiQ2VudHJhbCBBZnJpY2FuIFJlcHVibGljIl0gPC0gIkNBUiIKICBsaWZlX2V4cGVjdGFuY3lfMVtsaWZlX2V4cGVjdGFuY3lfMT09ICJVbml0ZWQgU3RhdGVzIG9mIEFtZXJpY2EiXSA8LSAiVVNBIgoKICBsaWZlX2dyYXBoPC0gbGlmZV9leHBlY3RhbmN5XzEgJT4lIAogIGdncGxvdChhZXMoeCA9IFllYXIsIHkgPSBgTGlmZSBleHBlY3RhbmN5YCwgY29sb3IgPSBDb3VudHJ5KSkgKwogIGdlb21fbGluZSgpICsKICAgIGxhYnModGl0bGUgPSAiTGlmZSBFeHBlY3RhbmNpZXMgYnkgQ291bnRyeSBmcm9tIDIwMDAgdG8gMjAxNSIsIHN1YnRpdGxlID0gIkRhdGU6IDIwMDAgdG8gMjAxNSIsIHggPSAgICAgICAgICAgICBlbGVtZW50X2JsYW5rKCksIHkgPSBlbGVtZW50X2JsYW5rKCkpKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSsKICAgIGZhY2V0X3dyYXAoIkNvdW50cnkiLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgICB0aGVtZSgKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpKQogIGdncGxvdGx5KGxpZmVfZ3JhcGgpCmBgYAoKClRoZSBhYm92ZSBpbnRlcmFjdGl2ZSBncmFwaCBhbGxvd3MgeW91IHRvIGhvdmVyIG92ZXIgdGhlIHllYXJzIHRvIHNlZSB3aGF0IGVhY2ggY291bnRyeSdzIGxpZmUgZXhwZWN0YW5jeSB3YXMgZHVyaW5nIHRoYXQgdGltZSBwZXJpb2QuIFRoZXkgYWxzbyBzaG93IGhvdyBlYWNoIGNvdW50cnkncyBsaWZlIGV4cGVjdGFuY3kgaGFzIGdyb3duIG92ZXIgdGltZS4gV2Ugc2VlIHRoYXQgdGhlIFVTQSdzIGhhcyBncm93biBxdWl0ZSBjb25zdGFudGx5LCB3aGlsZSB0aGUgVUsncyBoYXMgZGlwcGVkIGluIG1vcmUgcmVjZW50IHllYXJzLgoKCgpgYGB7ciwgZmlnLndpZHRoPTE4LCBmaWcuaGVpZ2h0PTEyLCBldmFsID0gRkFMU0V9CmxpZmVfZXhwZWN0YW5jeV8xIDwtIGxpZmVfZXhwZWN0YW5jeSAlPiUgCiAgc2VsZWN0KENvdW50cnksIGBMaWZlIGV4cGVjdGFuY3lgLCBZZWFyKSAlPiUgCiAgZmlsdGVyKENvdW50cnkgJWluJSBjKCJSdXNzaWFuIEZlZGVyYXRpb24iLCAiVW5pdGVkIEtpbmdkb20gb2YgR3JlYXQgQnJpdGFpbiBhbmQgTm9ydGhlcm4gSXJlbGFuZCIsICJKYXBhbiIsICJVbml0ZWQgU3RhdGVzIG9mIEFtZXJpY2EiLCAgIkJyYXppbCIsICJDb3N0YSBSaWNhIiwgIkF1c3RyYWxpYSIsICJOZXcgWmVhbGFuZCIsICJJbmRvbmVzaWEiLCAiU3dhemlsYW5kIiwgIkNlbnRyYWwgQWZyaWNhbiBSZXB1YmxpYyIsICJFZ3B5dCIpKSAlPiUgCiAgZHJvcF9uYShDb3VudHJ5LCBgTGlmZSBleHBlY3RhbmN5YCwgWWVhcikgJT4lIAogIGdyb3VwX2J5KENvdW50cnksIFllYXIpCgogIGxpZmVfZXhwZWN0YW5jeV8xW2xpZmVfZXhwZWN0YW5jeV8xPT0gIlJ1c3NpYW4gRmVkZXJhdGlvbiJdIDwtICJSdXNzaWEiCiAgbGlmZV9leHBlY3RhbmN5XzFbbGlmZV9leHBlY3RhbmN5XzE9PSAiVW5pdGVkIEtpbmdkb20gb2YgR3JlYXQgQnJpdGFpbiBhbmQgTm9ydGhlcm4gSXJlbGFuZCJdIDwtICJVSyIKICBsaWZlX2V4cGVjdGFuY3lfMVtsaWZlX2V4cGVjdGFuY3lfMT09ICJDZW50cmFsIEFmcmljYW4gUmVwdWJsaWMiXSA8LSAiQ0FSIgogIGxpZmVfZXhwZWN0YW5jeV8xW2xpZmVfZXhwZWN0YW5jeV8xPT0gIlVuaXRlZCBTdGF0ZXMgb2YgQW1lcmljYSJdIDwtICJVU0EiCgogbGlmZV9leHBlY3RhbmN5XzEgJT4lIAogIGdncGxvdChhZXMoeCA9IFllYXIsIHkgPSBgTGlmZSBleHBlY3RhbmN5YCwgY29sb3IgPSBDb3VudHJ5KSkgKwogIGdlb21fbGluZSgpICsKICAgIGxhYnModGl0bGUgPSAiTGlmZSBFeHBlY3RhbmNpZXMgYnkgQ291bnRyeSBmcm9tIDIwMDAgdG8gMjAxNSIsIHN1YnRpdGxlID0gIkRhdGU6IDIwMDAgdG8gMjAxNSIsIHggPSAgICAgICAgICAgICBlbGVtZW50X2JsYW5rKCksIHkgPSBlbGVtZW50X2JsYW5rKCkpICsKICAgIHRyYW5zaXRpb25fcmV2ZWFsKFllYXIpCiBhbmltX3NhdmUoIlRlc3QuZ2lmIikKYGBgCmBgYHtyfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiVGVzdC5naWYiKQpgYGAKCgpUaGlzIGdyYXBoIHNob3dzIHRoZSBzYW1lIHRyZW5kcyBhcyB0aGUgb25lIGFib3ZlLCBidXQgbWFrZXMgaXQgZWFzaWVyIGZvciB0aGUgdmlld2VyIHRvIGNvbXBhcmUgdGhlc2UgY291bnRyaWVzJyByYXRlcyBvZiBsaWZlIGV4cGVjdGFuY3kgZ3Jvd3RoIG92ZXIgdGltZSwgYW5kIHRvIHNlZSBob3cgbG93IHNvbWUgYXJlIHJlbGF0aXZlIHRvIG90aGVycy4KCgojIyBVc2luZyBSZWdyZXNzaW9ucyB0byBEZXRlcm1pbmUgVHJlbmRzIG9mIG90aGVyIFZhcmlhYmxlcwoKCmBgYHtyLCBmaWcud2lkdGg9NX0KcGxvdDEgPC0gbGlmZV9leHBlY3RhbmN5ICU+JQogIGZpbHRlcihDb3VudHJ5ICVpbiUgYygiUnVzc2lhbiBGZWRlcmF0aW9uIiwgIlVuaXRlZCBLaW5nZG9tIG9mIEdyZWF0IEJyaXRhaW4gYW5kIE5vcnRoZXJuIElyZWxhbmQiLCAiSmFwYW4iLCAiVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhIiwgICJCcmF6aWwiLCAiQXVzdHJhbGlhIiwgIk5ldyBaZWFsYW5kIikpICU+JQogIGdyb3VwX2J5KENvdW50cnkpICU+JSAKICBkcm9wX25hKEFsY29ob2wpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBBbGNvaG9sLCB5ID0gYExpZmUgZXhwZWN0YW5jeWApKSArCiAgZ2VvbV9qaXR0ZXIoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKwogIGxhYnMoeCA9ICJBbGNvaG9sIENvbnN1bXB0aW9uIChQZXJjZW50YWdlIG9mIFBvcHVsYXRpb24pIiwgeSA9ICJMaWZlIEV4cGVjdGFuY3kiKQoKcGxvdDIgPC0gbGlmZV9leHBlY3RhbmN5ICU+JQogIGZpbHRlcihDb3VudHJ5ICVpbiUgYygiUnVzc2lhbiBGZWRlcmF0aW9uIiwgIlVuaXRlZCBLaW5nZG9tIG9mIEdyZWF0IEJyaXRhaW4gYW5kIE5vcnRoZXJuIElyZWxhbmQiLCAiSmFwYW4iLCAiVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhIiwgICJCcmF6aWwiLCAiQXVzdHJhbGlhIiwgIk5ldyBaZWFsYW5kIikpICU+JQogIGdyb3VwX2J5KENvdW50cnkpICU+JSAKICBkcm9wX25hKGBUb3RhbCBleHBlbmRpdHVyZWApICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBgVG90YWwgZXhwZW5kaXR1cmVgLCB5ID0gYExpZmUgZXhwZWN0YW5jeWApKSArCiAgZ2VvbV9qaXR0ZXIoKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKwogIGxhYnMoeCA9ICJQZXJjZW50YWdlIG9mIEdvdmVybm1lbnQgU3BlbmRpbmcgb24gSGVhbHRoY2FyZSIsIHkgPSAiTGlmZSBFeHBlY3RhbmN5IikKCnBsb3RfZ3JpZChwbG90MSwgcGxvdDIsIGxhYmVscyA9ICJBVVRPIikKYGBgCgoKVG8gZXhwYW5kIG9uIG91ciBmaW5kaW5ncywgd2UgZGVjaWRlZCB0byBjb25kdWN0IG91ciBvd24gcmVzZWFyY2ggaW50byByZWdyZXNzaW9ucyBhbmQgY29ycmVsYXRpb25zIGluIG9yZGVyIHRvIGRldGVybWluZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gY2VydGFpbiB2YXJpYWJsZXMgYW5kIGxpZmUgZXhwZWN0YW5jaWVzLiBJbiB0aGUgYWJvdmUgZ3JhcGgsIHdlIGNhbiBzZWUgdGhhdCBvbiBhdmVyYWdlLCBhY3Jvc3Mgb3VyIHNlbGVjdGVkIGNvdW50cmllcywgdGhlcmUgaXMgYSBzdHJvbmcgbmVnYXRpdmUgY29ycmVsYXRpb24gYmV0d2VlbiBhbGNvaG9sIGNvbnN1bXB0aW9uIGFuZCBsaWZlIGV4cGVjdGFuY3kuIFRoYXQgaXMsIGFzIGFsY29ob2wgY29uc3VtcHRpb24gaW5jcmVhc2VzLCBsaWZlIGV4cGVjdGFuY3kgdGVuZHMgdG8gZmFsbC4gClRoZSBncmFwaCBuZXh0IHRvIGl0IHNob3dzIGEgc3Ryb25nIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIHBlcmNlbnRhZ2Ugb2YgZ292ZXJubWVudCBzcGVuZGluZyBvbiBoZWFsdGhjYXJlIGFuZCBsaWZlIGV4cGVjdGFuY3kuIFRoYXQgaXMsIGFzIHRoZSBnb3Zlcm5tZW50cyBhY3Jvc3MgdGhlc2UgY291bnRyaWVzIHNwZW5kcyBhIGhpZ2hlciBwZXJjZW50YWdlIG9mIHRoZWlyIGJ1ZGdldCBvbiBpbXByb3ZpbmcgaGVhbHRoY2FyZSwgbGlmZSBleHBlY3RhbmN5IHRlbmRzIHRpbyBpbmNyZWFzZS4KCgoKYGBge3IsIGZpZy5hbGlnbj0nbGVmdCcsIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xMn0KY29ycmVsYXRpb24xPC0gbGlmZV9leHBlY3RhbmN5ICU+JSAKICBmaWx0ZXIoU3RhdHVzPT0iRGV2ZWxvcGVkIikgJT4lCiAgc2VsZWN0KC1ZZWFyLCAtQ291bnRyeSwgLVN0YXR1cykgJT4lIAogIGRyb3BfbmEoKQpjb3JyZWxhdGlvbl9hbmltPC0KY29ycnBsb3QoY29yKGNvcnJlbGF0aW9uMSksdHlwZT0idXBwZXIiLG1ldGhvZD0iY2lyY2xlIix0aXRsZT0iQ29ycmVsYXRpb24gcGxvdCBiZXR3ZWVuIHZhcmlhYmxlcyIsbWFyPWMoMC4xLDAuMSwwLjEsMC4xKSwgaW5zaWc9ImJsYW5rIiwgbmEubGFiZWwgPSAiICIpCmBgYAoKYGBge3IsIGZpZy5hbGlnbj0nbGVmdCcsIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xMn0KY29ycmVsYXRpb24yPC0gbGlmZV9leHBlY3RhbmN5ICU+JSAKICBmaWx0ZXIoU3RhdHVzPT0iRGV2ZWxvcGluZyIpICU+JQogIHNlbGVjdCgtWWVhciwgLUNvdW50cnksIC1TdGF0dXMpICU+JSAKICBkcm9wX25hKCkKY29ycmVsYXRpb25fYW5pbTwtCmNvcnJwbG90KGNvcihjb3JyZWxhdGlvbjIpLHR5cGU9InVwcGVyIixtZXRob2Q9ImNpcmNsZSIsdGl0bGU9IkNvcnJlbGF0aW9uIHBsb3QgYmV0d2VlbiB2YXJpYWJsZXMiLG1hcj1jKDAuMSwwLjEsMC4xLDAuMSksIGluc2lnPSJibGFuayIpCmBgYAoKCiMjIENvbmNsdXNpb24gYW5kIExpbWl0YXRpb25zCgoKVGhlIG1haW4gZmluZGluZ3Mgd2UgdG9vayBmcm9tIG91ciBwcm9qZWN0IGFyZSAoaSkgdGhlcmUgaXMgYSBjbGVhciBkaXN0aW5jdGlvbiBiZXR3ZWVuIGxpZmUgZXhwZWN0YW5jaWVzIGluIGRldmVsb3BlZCB2cy4gZGV2ZWxvcGluZyBjb3VudHJpZXMuIERldmVsb3BlZCBjb3VudHJpZXMgdGVuZCB0byBoYXZlIGhpZ2hlciBsaWZlIGV4cGVjdGFuY2llcywgd2hpbGUgZGV2ZWxvcGluZyBjb3VudHJpZXMgdGVuZCB0byBoYXZlIG11Y2ggbG93ZXIgbGlmZSBleHBlY3RhbmNpZXMuIEZ1cnRoZXJtb3JlLCB3ZSBjYW4gc2VlIHRoYXQgdGhlIGxpZmUgZXhwZWN0YW5jaWVzIG92ZXIgdGltZSBpbiBkZXZlbG9wZWQgY291bnRyaWVzIGlzIGluY3JlYXNpbmcgYXQgYSBtdWNoIGZhc3RlciByYXRlIHRoYW4gdGhhdCBpbiBkZXZlbG9waW5nIGNvdW50cmllcy4gKGlpKSBJbmNyZWFzZWQgYWxjb2hvbCBjb25zdW1wdGlvbiB0ZW5kcyB0byBkZWNyZWFzZSBsaWZlIGV4cGVjdGFuY3ksIHdoaWxlIGluY3JlYXNlZCBnb3Zlcm5tZW50IHNwZW5kaW5nIG9uIGhlYWx0aGNhcmUgdGVuZHMgdG8gaW5jcmVhc2UgbGlmZSBleHBlY3RhbmN5LgoKCgo=